home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TPTUTR~1.ZIP / PASCAL21.TXT < prev    next >
Text File  |  1996-03-21  |  12KB  |  321 lines

  1.                        Turbo Pascal for DOS Tutorial
  2.                            by Glenn Grotzinger
  3.                          Part 21: Use of the BGI.
  4.                  copyright (c) 1995-6 by Glenn Grotzinger
  5.  
  6. Here is a solution to the problem presented last time.
  7.  
  8. program part20; uses dos;
  9.  
  10.   const
  11.     oneminute = 273;  { # of timer ticks that happens in 15 seconds }
  12.  
  13.   var
  14.     saveint09, saveint1c: procedure;
  15.     timecounter, keycounter: integer;
  16.     achar: char;
  17.     timeup: boolean;
  18.  
  19.   {$F+}
  20.   procedure counttime; interrupt;
  21.     begin
  22.       inc(timecounter);
  23.       if timecounter = oneminute then
  24.         timeup := true;
  25.       inline($9C);
  26.       saveint1c;
  27.     end;
  28.  
  29.   procedure countkeys; interrupt;
  30.     begin
  31.       inc(keycounter);
  32.       inline($9C);
  33.       saveint09;
  34.     end;
  35.  
  36.   {$F-}
  37.  
  38.   begin
  39.     timeup := false;
  40.     timecounter := 0;
  41.     keycounter := 0;
  42.     getintvec($09, @saveint09);
  43.     getintvec($1C, @saveint1C);
  44.     setintvec($09, @countkeys);
  45.     setintvec($1C, @counttime);
  46.  
  47.     while timeup = false do
  48.       read(achar);
  49.  
  50.     setintvec($09, @saveint09);
  51.     setintvec($1C, @saveint1C);
  52.     writeln('There were ', keycounter div 2, ' keys pressed.');
  53.   end.
  54.  
  55.  
  56. BGI Intro
  57. =========
  58. This part is basically about using the Borland Graphics Interface.  It is
  59. not generally recommended to use it -- use assembler instead to make it a
  60. lot quicker, and smaller.... but due to demand, and the ability to use the
  61. BGI for basic graphics, we will talk about use of the BGI.  For heavy use
  62. of graphics, assembler is indeed better....
  63.  
  64. BGI loader
  65. ==========
  66. Here, I will describe how to make the BGI files functionally more useable
  67. than in their current state....Compile with looking for the external BGI
  68. files is fine, but will run into an annoyance quick, especially with a
  69. distributed utility...it is easier to have the EXE available with the BGI
  70. files binded to it than to make a user keep track of the BGI files....
  71.  
  72. There is a utility available in TP called BINOBJ.  The BGI files are video
  73. control files, while CHR files are font definition files.  They both are
  74. usable in graphics as binary files...and that is what BINOBJ does...it
  75. converts binary files to OBJect files, which may be handled like described
  76. before.  The proper usage of this utility is...
  77.  
  78. BINOBJ <binary file name> <object file name> <internal procedure name>
  79.  
  80. Here is a sample command-line.  To convert VESA16.BGI to an OBJ, do this:
  81.  
  82. BINOBJ VESA16.BGI VESA16.OBJ Vesa16driver
  83.  
  84. Locate the BGI files that should be in your TP/BGI directory.
  85. You will need to copy them off to a separate directory.
  86.  
  87. After you convert all BGI files like this, I recommend you write a unit
  88. to link the BGI files in -- optionally, if you need fonts, you may write
  89. a unit to link those in likewise.  Be sure to define your proper external
  90. procedures like it needs to be done.  Make use of meaningful
  91. names, as you will have to remember them to make use of the graphics set.
  92. For example, I call my unit bgivideo; for each procedure, I put the first
  93. 8 chars of the name of the file, and then driver for the BGI files.  These
  94. function names will be easy to remember when we need to use them.
  95.  
  96. Going into Graphics Mode
  97. ========================
  98. Now, hopefully you have your BGI video unit ready now, and sitting in
  99. whatever directory you use to place your pascal code.  Now we will discuss
  100. about how to go into graphics mode using the BGI.
  101.  
  102. Generally, going to graphics mode initially would require setting up the
  103. BGI unit you created, and then performing an autodetect on the graphics,
  104. followed by an init into graphics mode.
  105.  
  106. Let us look at some sample code...
  107.  
  108. program video_example_1;{1} uses graph, bgivideo;
  109.  
  110. var
  111.   graphicsdriver, graphicsmode: integer;
  112.  
  113. procedure errormessage(driver: string);
  114.   begin
  115.     writeln('There was an error: ', grapherrormsg(graphresult), driver);
  116.     halt(1);
  117.   end;
  118.  
  119. begin
  120. {2}if (registerbgidriver(@attdriver) < 0) then
  121.      errormessage('ATT');
  122.    if (registerbgidriver(@cgadriver) < 0) then
  123.      errormessage('CGA');
  124.    if (registerbgidriver(@egavgadriver) < 0) then
  125.      errormessage('EGA/VGA');
  126.    if (registerbgidriver(@hercdriver) < 0) then
  127.      errormessage('Herc');
  128.    if (registerbgidriver(@pc3270driver) < 0) then
  129.      errormessage('PC 3270');
  130.  
  131. {3}detectgraph(graphicsdriver, graphicsmode);
  132.    graphicsdriver := Detect;
  133. {4}initgraph(graphicsdriver, graphicsmode, '');
  134. {5}if GraphResult <> grOk then
  135.     begin
  136.       writeln('Video error.');
  137.       halt(1);
  138.     end;
  139.  
  140. {6}repeat
  141.     putpixel(random(getmaxx), random(getmaxy), random(getmaxcolor));
  142.    until keypressed;
  143.    readln;
  144.  
  145. {7}closegraph;
  146. end.
  147.  
  148. This is basically a random pixel place system using the video mode in the
  149. recommended auto-detect.  Let's go through a few of the features of the
  150. code, which were marked by {}'s.
  151.  
  152. {1} As we see, the graph, and bgivideo units are used here.  The graph
  153. unit is the basic function interface for the BGI system.  We are familiar
  154. with bgivideo from earlier.
  155.  
  156. {2} RegisterBGIDriver() must be called for any and all realistic
  157. possibilities. I recommend that only the ones listed really need to be
  158. checked.  If the function is less than zero, then there is a problem.
  159. The errormessage function holds a function called grapherrormsg() which
  160. will output a direct error as to why things aren't working right.
  161.  
  162. {3} detectgraph detects the graphics card.  it takes integers represented
  163. by graphicsdriver, and graphicsmode....graphicsdriver will hold the
  164. recommended video type, and graphicsmode will hold the recommended video
  165. mode (it can be changed).  This is why we registered all the drivers...it
  166. will use whichever one it needs, and ultimately, the program will work with
  167. all video modes.
  168.  
  169. {4} initgraph() takes us into graphics mode.  It is called basically as
  170. indicated in the program.  the third param '', is for when we load the
  171. BGI files externally.  To do that, do not include BGIVIDEO and provide
  172. a path to the BGI files....to get a full auto-detect capability, just
  173. make all the BGI files available....it is easier in the long run to have
  174. the BGI files combined in the exec.
  175.  
  176. {5} For almost any graphics function, a variable called graphresult is
  177. changed.  There are graphics mode constants, which will be covered later,
  178. which are in there representing different things.  grok is the one which
  179. indicates that things are OK.
  180.  
  181. {6} This is the real meat of the procedure.  It keeps placing pixels of
  182. random position and color on the screen until a key is pressed.  getmaxx
  183. is the maximum screen position on the x axis.  getmaxy is the maximum screen
  184. position on the y axis.  Graphics screens have the same kind of dimensional
  185. setup as the crt graphics screens do.  The putpixel procedure takes a
  186. x, y coordinate, then a color...getmaxcolor is a constant that holds the
  187. maximum # of colors present in the current video mode.
  188.  
  189. {7} Closegraph is pretty much self-explanatory.  It shuts down graphics mode
  190. and takes us back to text.
  191.  
  192. BGI Font Usage
  193. ==============
  194. The CHR files you saw, are font files, which have an ability to be used in
  195. graphics programs....
  196.  
  197. These files can be converted to OBJs, and I recommend that you do so for
  198. purposes of using the fonts.....
  199.  
  200. Here is a small example of loading and using fonts -- I'm not repeating
  201. the video load code, so I will omit that....
  202.  
  203. program video_example; uses graph, bgivideo;
  204.  
  205. var
  206.   graphicsdriver, graphicsmode: integer;
  207.   i: integer;
  208.  
  209. {1} {$L GOTH.OBJ}
  210. procedure Gothfont; external;
  211.  
  212. procedure errormessage(driver: string);
  213.   begin
  214.     writeln('There was an error: ', grapherrormsg(graphresult), driver);
  215.     halt(1);
  216.   end;
  217.  
  218. begin
  219.   { This is the video load code }
  220.  
  221. {2}  if registerbgifont(@gothfont) < 0 then
  222.       errormessage('Script font');
  223.  
  224.     i := 100;
  225. {3}  settextstyle(DefaultFont, HorizDir, 1);
  226. {4}  setcolor(blue);
  227. {5}  outtextxy(20, i, 'This is the DEFAULT font.');
  228. {6}  inc(i, textheight('T')+2);
  229.      readln;
  230. {7}  cleardevice;
  231.      settextstyle(Gothicfont, horizdir, 2);
  232.      setcolor(green);
  233.      outtextxy(20, i, 'This is the GOTHIC font.');
  234.      readln;
  235.      closegraph;
  236. end.
  237.  
  238. This basically goes into graphic mode, and writes those two statements to
  239. the screen.  We will go through the areas marked by {}'s..
  240.  
  241. {1} This is exactly like I described before.  This is how we load the CHR
  242. file to not make it separate.  We do it exactly like the BGI files, and
  243. set them up as external OBJ files.
  244.  
  245. {2} registerbgifont works exactly like registerbgidriver does...it registers
  246. the font into the program -- load fonts judiciously -- only if you need
  247. them.
  248.  
  249. {3} settextstyle() changes the font, direction, and size....things can
  250. be written out either horizontally, or vertically.  Fonts letters are 8X8
  251. pixels in size...so it is also possible to zoom the fonts...the third
  252. is the factor in which it may be done...a 2 in the third parameter makes the
  253. letters 16X16 pixels, and so on and so forth.
  254.  
  255. {4} setcolor(blue) sets the foreground graphics draw color to blue.
  256.  
  257. {5} outtextxy() puts out a text statement at coordinate x, y for graphics
  258. mode.
  259.  
  260. {6} textheight is a function which guages the height in pixels of a text
  261. placed in the statement.
  262.  
  263. Font file names
  264. ===============
  265. DefaultFont; TriplexFont; SmallFont; SanSerifFont; GothicFont; represent
  266.   fonts.
  267. HorizDir; VertDir;
  268.  
  269. A VERY QUICK overview of commands available from BGI
  270. ====================================================
  271. Due to the volume of commands available, all of them can not be sufficiently
  272. covered in the space of this document.  Most if not all of them are
  273. straight-forward to use.  Look at page 185 of the Turbo Pascal language
  274. guide for a list of all of the BGI commands.
  275.  
  276. Conclusion
  277. ==========
  278. IMO, Borland made the BGI very hard to use.  I have stumbled across many
  279. things that looked like bugs in their system (I couldn't use their included
  280. script font).  Beyond that, it works OK for light-duty graphics.  Anything
  281. beyond that truly needs assembler.
  282.  
  283. There is enough knowledge here to set up and make use of BGI (not with-
  284. standing the basic commands in that list -- for example, rectangle....
  285. draws a rectangle....).
  286.  
  287. As another side note, you may have noticed that executables you create
  288. using methods described here are large.  Get a program such as PKLITE,
  289. or LZEXE, and compress it.  They compress down about 45-55%, in my
  290. experience.  Graphics programs using BGI seem to characteristically
  291. compile to be large.
  292.  
  293. Practice Programming Problem #21
  294. ================================
  295. Make a program which will successively place rectangles on the screen in
  296. random colors.  Since it is hard to illustrate what I'm wanting, given
  297. this medium, I will place the final executable, named part21.EXE in the
  298. file at Garbo.   Cut and paste the document after you save this, please.
  299. Here are the basic stats behind the program:
  300.  
  301. 1) Squares are used.  use the rectangle() function.  it takes for arguments,
  302. the coordinates of the upper left hand corner, and the lower right hand
  303. corner.
  304. 2) Each square drawn successively is one pixel larger than the previous....
  305. 3) Continually draw the squares until the user presses a key.
  306. 4) The colors are randomly determined.
  307.  
  308. Look at the program to get an idea of what I am looking for.  Also please
  309. send comments back to ggrotz@2sprint.net if it happens to not work on your
  310. system for no readily apparent reason.  I need to get an idea of how well
  311. these sample video routines work.
  312.  
  313. Next Time
  314. =========
  315. Things will be indeterminate.  I will be covering object-oriented program-
  316. ming.  As I have not set down and figured out how many parts object-oriented
  317. programming will take to cover, I do not know.
  318.  
  319. E-mail ggrotz@2sprint.net and suggest anything that has to do with TP, which
  320. I may have not covered.  If it sounds good, I will cover it!
  321.